#include "Settings.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
#include <list>
#include <string>

Settings::Settings()
{
	char directory[128];
	GetCurrentDirectoryA( 128, directory );
	m_baseDirectory = directory;
}

Settings::~Settings()
{
	m_settingsMap.clear();
}

void Settings::RegisterVariable(std::string name, Pointer<Dator> var)
{
	m_settingsMap[name] = var;
}

void Settings::setVariable(std::string& name, std::string& value, int bias)
{
	if (m_settingsMap.find(name) == m_settingsMap.end())
		return;							// Setting does not exist
	if (m_settingsMap[name]->MultiValued())
	{
		std::list<std::string> valueList;

		if (value.find(';') != -1)
		{
			int first = 0, last;

			while ((last = value.find(';',first)) != -1)
			{
				valueList.push_back(value.substr(first, last - first));
				first = last + 1;
			}
			valueList.push_back(value.substr(first));
		} else
		{
			valueList.push_back(value);
		}

		for (std::list<std::string>::iterator it = valueList.begin(); it != valueList.end(); ++it)
		{
			if (bias > 0)
			{
				(*m_settingsMap[name]) += (*it);
			} else if (bias < 0)
			{
				(*m_settingsMap[name]) -= (*it);
			} else
			{
				(*m_settingsMap[name]) = (*it);
			}
		}
	} else
	{
		(*m_settingsMap[name]) = value;
	}
}

void Settings::ParseSetting(std::string str)
{
  int bias = 0;
  std::string name, value;
  //test for bias
  if (str.length() < 1)
	  return;
  if ((str[0] == '+')||(str[0] == '-'))
  {
    bias = ((str[0]=='+') * 2) - 1; //+ maps to 1*2-1=1, - maps to 0*2-1=-1
    str = str.substr(1); //remove the first character from the string
  }
  //test for '='
  int eqPos = str.find('=');
  if(eqPos != -1)
  {
    //there's an = sign in there
    //so split either side of it
    name=str.substr(0,eqPos);
    value=str.substr(eqPos+1);
  }else
  {
    //there's no equal sign
    //we use the bias to construct a boolean value
    //so that flags can be +flag (mapping to flag=1) or -flag (mapping to flag=0)
    name = str;
    char szBuf[5];
    sprintf(szBuf,"%i", (bias+1) / 2);
    value = szBuf;
  }
  //set the variable
  setVariable(name, value, bias);
}


void Settings::ParseFile(std::string filename)
{
	std::ifstream in(filename.c_str());
	if (!in.is_open())
		return;

	while(!in.eof())
	{
		char buff[1024];
		in.getline(buff, 1024);
		ParseSetting(buff);
	}
}

std::string& Settings::getDirectory()
{
	return m_baseDirectory;
}

